Design Patterns - Strategy Pattern
17 Jul 2018Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from the clients that use it.
Intent | Enables you to use different business rules or algorithms depending on the context in which they occur |
Problem | The selection of an algorithm that needs to be applied depends on the client making the request or the data being acted on. |
Solution | Separate the selection of algorithm from the implementation of the algorithm. Allows for the selection to be made based upon context. |
Participants and Collaborators | Strategy declares an interface common to all supported algorithms, and specifies how the different algorithms are used. Concrete Strategy implements these different algorithms using Strategy interface. Context uses a specific Concrete Strategy with a reference of the type Strategy |
Consequences | The Strategy pattern defines a family of algorithms. Switch or Conditional can be eliminated |
Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.art.designpatterns.strategy; | |
import com.google.common.collect.Lists; | |
import java.util.List; | |
public class StrategyDemo { | |
public static void main(String[] args) { | |
PromotionStrategy halfOffPromo = new HalfOffPromotionStrategy(); | |
PromotionStrategy clearancePromo = new ClearancePromotionStrategy(); | |
Customer customer1 = new Customer(halfOffPromo); | |
customer1.addItem(100.0); | |
customer1.addItem(50.0); | |
customer1.addItem(20.0); | |
System.out.println("Customer 1"); | |
System.out.println("Total: " + customer1.getTotalBeforePromo()); | |
System.out.println("Total (After Promo): " + customer1.getTotalAfterPromo()); | |
Customer customer2 = new Customer(clearancePromo); | |
customer2.addItem(100.0); | |
customer2.addItem(50.0); | |
customer2.addItem(20.0); | |
System.out.println("Customer 2"); | |
System.out.println("Total: " + customer2.getTotalBeforePromo()); | |
System.out.println("Total (After Promo):" + customer2.getTotalAfterPromo()); | |
} | |
} | |
class Customer { | |
private List<Double> items; | |
private PromotionStrategy promotionStrategy; | |
public Customer(PromotionStrategy promotionStrategy) { | |
this.promotionStrategy = promotionStrategy; | |
this.items = Lists.newArrayList(); | |
} | |
public void addItem(Double item){ | |
items.add(item); | |
} | |
public double getTotalBeforePromo(){ | |
double total = items.stream().mapToDouble(i -> i).sum(); | |
return total; | |
} | |
public double getTotalAfterPromo(){ | |
double total = getTotalBeforePromo(); | |
double promotion = promotionStrategy.getPromotion(total); | |
return total - promotion; | |
} | |
} | |
interface PromotionStrategy{ | |
double getPromotion(Double totalAmount); | |
} | |
class HalfOffPromotionStrategy implements PromotionStrategy { | |
@Override | |
public double getPromotion(Double totalAmount) { | |
return totalAmount * 0.5; | |
} | |
} | |
class ClearancePromotionStrategy implements PromotionStrategy{ | |
@Override | |
public double getPromotion(Double totalAmount) { | |
return totalAmount * 0.75; | |
} | |
} |